#include "global.h"

/* 定时器参数宏定义 */
#define TIM_PERIOD 5000  // ARR自动重装载值（实际计数值为TIM_PERIOD-1）
#define TIM_PRESCALER 36 // PSC预分频系数（实际分频值为TIM_PRESCALER-1）
/* 定时周期计算公式：
   - 定时器时钟 = 系统时钟 / (PSC + 1)
   - 中断周期 = (ARR + 1) * (1/定时器时钟)
   参数计算（基于36MHz系统时钟）：
   - 预分频后频率 = 36MHz / 36 = 1MHz
   - 定时周期 = (1000) * (1/1MHz) = 1ms */

/**
 * @brief 初始化 TIM1 定时器
 *
 * 该函数配置 TIM1 定时器，使其以 5ms 的周期产生中断。
 */
void tim_init(void)
{
    /* 时钟使能 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 使能TIM1时钟（APB2总线）

    /* 时基单元配置 */
    TIM_InternalClockConfig(TIM1); // 选择内部时钟源（默认使用APB总线时钟）

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     // 时钟分频（与输入捕获滤波器相关）
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
    TIM_TimeBaseInitStructure.TIM_Period = TIM_PERIOD - 1;          // 自动重装载值（从0计数到此值）
    TIM_TimeBaseInitStructure.TIM_Prescaler = TIM_PRESCALER - 1;    // 预分频系数（实际值需-1）
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            // 重复计数器（高级定时器功能）
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);             // 应用配置

    /* 中断配置 */
    TIM_ClearFlag(TIM1, TIM_FLAG_Update);      // 清除首次上电可能存在的更新标志
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); // 使能更新中断

    /* NVIC配置 */
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;        // TIM1更新中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级0（最高）
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 子优先级0（最高）
    NVIC_Init(&NVIC_InitStructure);                           // 应用NVIC配置

    /* 启动定时器 */
    TIM_Cmd(TIM1, ENABLE); // 使能定时器计数器开始工作
}

/**
 * @brief TIM1 更新中断服务函数
 *
 * 该函数在 TIM1 定时器产生更新中断时被调用，周期为 5ms。
 */
void TIM1_UP_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM1, TIM_IT_Update) == SET) // 确认更新中断触发
    {
        TIM_ClearITPendingBit(TIM1, TIM_IT_Update); // 必须清除中断标志
        button_ticks();                             // 多按键处理函数
        beep_ticks();                               // 蜂鸣器控制
        txRemote_send();                            // 发送tx遥控器数据
    }
}
